package common

import (
	"fmt"
	"github.com/go-redis/redis" // 实现了redis连接池
	"snow-im/app/constants/common"
	"snow-im/config"

	"strconv"

	"time"
)

var redisUrl, pikaUrl string
var RedisTool, PikaTool *RedisHelpler
func InitRedis() {
	redisUrl = config.GetConf().Redis.Master.Host+":"+ strconv.Itoa(config.GetConf().Redis.Master.Port)
	RedisTool = &RedisHelpler{
		client: getClient(redisUrl, config.GetConf().Redis.Master.Password),
	}
	//PikaTool = &RedisHelpler{
	//	client: getClient(pikaUrl, ""),
	//}
	SendLog("init redis","",common.LOG_DEBUG)
}

// 初始化redis链接池
func getClient(url string, password string) *redis.Client {
	var client *redis.Client
	if password != "" {
		client = redis.NewClient(&redis.Options{
			Addr:        url,              // Redis地址
			Password:    "",               // Redis账号
			DB:          0,                // Redis库
			PoolSize:    config.GetConf().Redis.Option.MaxConns,         // Redis连接池大小
			MaxRetries:  3,                // 最大重试次数
			IdleTimeout: 10 * time.Second, // 空闲链接超时时间
		})
	} else {
		client = redis.NewClient(&redis.Options{
			Addr:        url,              // Redis地址
			Password:    password,         // Redis账号
			DB:          0,                // Redis库
			PoolSize:    config.GetConf().Redis.Option.MaxConns,         // Redis连接池大小
			MaxRetries:  3,                // 最大重试次数
			IdleTimeout: 10 * time.Second, // 空闲链接超时时间
		})
	}

	_, err := client.Ping().Result()
	if err != nil {
		SendLog("redis connect",err,common.LOG_ERR)
	}
	return client
}

type RedisHelpler struct {
	client *redis.Client
}

func (this *RedisHelpler) KeyGet(key string) interface{} {
	rs, _ := this.client.Get(key).Result()
	return rs
}
func (this *RedisHelpler) KeyDelete(key string) interface{} {
	rs, _ := this.client.Del(key).Result()
	return rs
}
func (this *RedisHelpler) KeySet(key string,val interface{},duration time.Duration) interface{} {
	rs, _ := this.client.Set(key,val,duration).Result()
	return rs
}
// 向key的hash中添加元素field的值
func (this *RedisHelpler) HashSet(key, field string, data interface{}) {
	err := this.client.HSet(key, field, data)
	if err != nil {
		SendLog("Redis HSet Error:", err,common.LOG_ERR)
	}
}

// 批量向key的hash添加对应元素field的值
func (this *RedisHelpler) BatchHashSet(key string, fields map[string]interface{}) string {
	val, err := this.client.HMSet(key, fields).Result()
	if err != nil {
		SendLog("Redis HMSet Error:", err,common.LOG_ERR)
	}
	return val
}

// 通过key获取hash的元素值
func (this *RedisHelpler) HashGet(key, field string) string {
	result := ""
	val, err := this.client.HGet(key, field).Result()
	if err == redis.Nil {
		SendLog("Key Doesn't Exists:", err,common.LOG_ERR)
		return result
	} else if err != nil {
		SendLog("Redis HGet Error:", err,common.LOG_ERR)
		return result
	}
	return val
}

// 批量获取key的hash中对应多元素值
func (this *RedisHelpler) BatchHashGet(key string, fields ...string) map[string]interface{} {
	resMap := make(map[string]interface{})
	for _, field := range fields {
		var result interface{}
		val, err := this.client.HGet(key, fmt.Sprintf("%s", field)).Result()
		if err == redis.Nil {
			resMap[field] = result
		} else if err != nil {
			resMap[field] = result
		}
		if val != "" {
			resMap[field] = val
		} else {
			resMap[field] = result
		}
	}
	return resMap
}

// 获取自增唯一ID
func (this *RedisHelpler) Incr(key string) int {
	val, err := this.client.Incr(key).Result()
	if err != nil {
		SendLog("Redis Incr Error:", err,common.LOG_ERR)
	}
	return int(val)
}

// 添加集合数据
func (this *RedisHelpler) SetAdd(key string, val interface{}) {
	this.client.SAdd(key, val)
}
// 删除集合数据
func (this *RedisHelpler) SetDel(key string, val interface{}) {
	this.client.SRem(key, val)
}
//操作List
func(this *RedisHelpler) ListLen(key string)int64{
	len,err := this.client.LLen(key).Result()
	if err !=nil{
		SendLog("err",err,common.LOG_ERR)
	}
	return len
}
func (this *RedisHelpler) Blpop(key string){
	this.client.BLPop(time.Second*5,key)
}
func (this *RedisHelpler) ZCard(key string) int64{
	rs,err := this.client.ZCard(key).Result()
	if err !=nil{
		SendLog("ZenLenErr",err,common.LOG_ERR)
	}
	return rs
}

func (this *RedisHelpler) ZRemByRank(key string,start int64 ,end int64){
	this.client.ZRemRangeByRank(key,start,end)
}
func (this *RedisHelpler) Rpush(key string,val interface{}){
	this.client.RPush(key,val)
}

// 从集合中获取数据
func (this *RedisHelpler) SetGet(key string) []string {
	val, err := this.client.SMembers(key).Result()
	if err != nil {
		SendLog("集合err", err,common.LOG_ERR)
	}
	return val
}
//判断集合元素是否存在
func (this *RedisHelpler) ExistKey(key string,val interface{}) bool{
	rs,err := this.client.SIsMember(key,val).Result()
	if err != nil {
		SendLog("Existerr", err,common.LOG_ERR)
	}
	return rs
}

func (this *RedisHelpler) Zadd(key string,val interface{},score int64){
	var member = redis.Z{
		Score:  float64(score),
		Member: val,
	}
	this.client.ZAdd(key,member)
}
func (this *RedisHelpler)ZRangeByScoreForAll(key string,start string,max string) []redis.Z {
	var opt = redis.ZRangeBy{
		Min:    start,
		Max:    max ,
	}
	rs ,err := this.client.ZRangeByScoreWithScores(key,opt).Result()
	if err != nil {
		SendLog("ZRangeByScoreErr", err,common.LOG_ERR)
	}
	return rs
}
func (this *RedisHelpler) Xadd(stream string,val map[string]interface{}) string {
	args := &redis.XAddArgs{
		Stream: stream,
		Values: val,
	}
	rs ,err := this.client.XAdd(args).Result()
	if err != nil {
		SendLog("Xadd", err,common.LOG_ERR)
	}
	return rs
}
func (this *RedisHelpler) Xgroup(stream string,group string) string {

	rs ,err := this.client.XGroupCreate(stream,group,"$").Result()
	if err != nil {
		SendLog("Xadd", err,common.LOG_ERR)
	}
	return rs
}
func (this *RedisHelpler) XReadGroup(stream string,group string,consume string) []redis.XStream {
	args := &redis.XReadGroupArgs{
		Group: group,
		Streams: []string{stream,">"},
		Consumer: consume,
		Count: 1,
		NoAck: false,
	}
	rs ,err := this.client.XReadGroup(args).Result()
	if err != nil {
		SendLog("Xreadgroup", err,common.LOG_ERR)
	}
	return rs
}
//管道操作
func (this *RedisHelpler) GetPipe() redis.Pipeliner {
	return this.client.TxPipeline()

}

